#include <stdint.h>

#include "rtthread.h"
#include "shell.h"

#include "SEGGER_RTT.h"
#include "stm32f1xx_hal.h"

extern uint32_t SystemCoreClock;
extern void SystemClock_Config(void);

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
/*
 * Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
 * the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
 */
#define RT_HEAP_SIZE (8 * 1024)
static rt_uint8_t rt_heap[RT_HEAP_SIZE];

RT_WEAK void *rt_heap_begin_get(void)
{
    return rt_heap;
}

RT_WEAK void *rt_heap_end_get(void)
{
    return rt_heap + RT_HEAP_SIZE;
}
#endif

void rt_hw_board_init(void)
{
    HAL_Init();

    SystemClock_Config();

#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}

#ifdef RT_USING_CONSOLE

static int log_system_core_clock(void)
{
    rt_kprintf("SystemCoreClock: %dHz\n", SystemCoreClock);
    return 0;
}
INIT_PREV_EXPORT(log_system_core_clock);

static int segger_rtt_console_init(void)
{
    SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
    SEGGER_RTT_ConfigDownBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
    return 0;
}
INIT_BOARD_EXPORT(segger_rtt_console_init);

void rt_hw_console_output(const char *str)
{
    SEGGER_RTT_Write(0, str, rt_strlen(str));
}

char rt_hw_console_getchar(void)
{
    static char ch = 0;

    if (SEGGER_RTT_ReadNoLock(0, &ch, sizeof(ch)))
    {
        if (ch == '\r')
        {
            return -1;
        }
        return ch;
    }

    rt_thread_mdelay(1);

    return -1;
}

#endif
